/*
 * mapImage.java
 *
 * Copyright (C) 2008 Paul Nettleship
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 */
package staticTrailExplorer;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

/**
 *
 * @author codebauer
 */
public class mapImage implements mapDataIF
   {
   private tileMap map;
   private BufferedImage mapImage;
   private AffineTransform calTransform= new AffineTransform();
   
   public void init(tileMap map)
      {
      this.map = map;
      map.calibrated = false;
      }

   public void openInput(File phile) throws IOException
      {
      File imageFile = phile;
      mapImage = ImageIO.read(imageFile);
      }

   public void openOutput(File phile)
      {
      }

      public void close() throws IOException
      {
      }

   public location getDefaultStartLocation()
      {
      return new location(0,0,location.maxZoom);
      }

   /* Note: x & y are pixle coords */
   public BufferedImage loadMapTile(location loc)
      {
      if( mapImage == null )
         return null;

      BufferedImage tile = new BufferedImage(map.tileWidth, map.tileHeight, mapImage.getType());
      int tileX = loc.getTileX(map);
      int tileY = loc.getTileY(map);
      int zoom = map.getScreenRef().getZoom();

      Graphics2D g2d = (Graphics2D)tile.createGraphics();
      AffineTransform t = new AffineTransform();
      t.translate(-map.tileWidth * tileX, -map.tileHeight * tileY);
      t.scale( Math.pow(2,zoom-location.maxZoom),Math.pow(2,zoom-location.maxZoom) );
      t.concatenate(calTransform);

      g2d.drawImage(mapImage, t, null);
      g2d.dispose();
      return tile;
      }

   public void saveMapTile(BufferedImage tile, location loc)
      {
      String text = "Can not save " + map.name + " not supported.\n";
      text += "Try selecting another window!";
      JOptionPane.showMessageDialog(null,text,"Warning",JOptionPane.PLAIN_MESSAGE);
      }

   public void setCalibration()
      {
      /* Set image to natural zoom level */
      map.getScreenRef().setZoom( location.maxZoom );
      
      /* Get markers as coords on image */
      double ucalm0x =   map.uncalibratedMarks[0].getPixelX(map);
      double ucalm0y =   map.uncalibratedMarks[0].getPixelY(map);
      double ucalm1x =   map.uncalibratedMarks[1].getPixelX(map);
      double ucalm1y =   map.uncalibratedMarks[1].getPixelY(map);
      double calm0x  = tileMap.calibratedMarks[0].getPixelX(map);
      double calm0y  = tileMap.calibratedMarks[0].getPixelY(map);
      double calm1x  = tileMap.calibratedMarks[1].getPixelX(map);
      double calm1y  = tileMap.calibratedMarks[1].getPixelY(map);
      
      /* Calc diifs */
      double calDifX  =  calm0x -  calm1x;
      double calDifY  =  calm0y -  calm1y;
      double ucalDifX = ucalm0x - ucalm1x;
      double ucalDifY = ucalm0y - ucalm1y;

      /* Some trig */
      double scale = (Math.sqrt((calDifX*calDifX)+(calDifY*calDifY)))/(Math.sqrt((ucalDifX*ucalDifX)+(ucalDifY*ucalDifY)));
      double angle = Math.atan(calDifY/calDifX) - Math.atan(ucalDifY/ucalDifX);

      /* Init transform */
      calTransform.translate(calm0x,calm0y);
      calTransform.scale(scale, scale);
      calTransform.rotate(angle);
      calTransform.translate(-ucalm0x, -ucalm0y);

      /* Change screen ref, and set map to calibrated */
      map.getScreenRef().set((int)(calm0x+calm1x)/2, (int)(calm0y+calm1y)/2, location.maxZoom);
      map.calibrated = true;

      /* Debug prints */
      System.out.print("scale="+scale+" angle="+angle+"\n");
      System.out.print("cal0_x="+calm0x+" cal0_y=="+calm0y+"\n");
      System.out.print("cal1_x="+calm1x+" cal1_y=="+calm1y+"\n");
      System.out.print("ucal0_x="+ucalm0x+" ucal0_y=="+ucalm0y+"\n");
      System.out.print("ucal1_x="+ucalm1x+" ucal1_y=="+ucalm1y+"\n");
      System.out.print(calTransform.transform(new Point.Double(ucalm0x,ucalm0y),null));
      System.out.print(calTransform.transform(new Point.Double(ucalm1x,ucalm1y),null)+"\n");
      }

}
